﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml;
using SHomeWorkshop.LunarPresentation.Adorners;
using SHomeWorkshop.LunarPresentation.Interfaces;

namespace SHomeWorkshop.LunarPresentation.Expressions
{
    public class BaseText : Expression, ICollapsed, IAutoWrap
    {
        public BaseText(SubPanel rootPanel, SubPanel parentPanel, Editor editor)
            : base(rootPanel, parentPanel, editor)
        {
            textBlock = new TextBlock() { Padding = BaseText.textPadding, TextWrapping = TextWrapping.Wrap };
            textBlock.Foreground = ExForeground;
            textBlock.PreviewMouseDown += new MouseButtonEventHandler(textBlock_PreviewMouseDown);
            this.mainBorder.Child = textBlock;

            textBlock.MouseLeftButtonDown +=
                new System.Windows.Input.MouseButtonEventHandler(textBox_MouseLeftButtonDown);
            textBlock.MouseLeftButtonUp +=
                new System.Windows.Input.MouseButtonEventHandler(textBox_MouseLeftButtonUp);
            textBlock.MouseRightButtonDown += new System.Windows.Input.MouseButtonEventHandler(textBox_MouseRightButtonDown);

            textBlock.MouseEnter += new System.Windows.Input.MouseEventHandler(textBox_MouseEnter);
            textBlock.MouseLeave += new System.Windows.Input.MouseEventHandler(textBox_MouseLeave);

            #region 绑定最大宽度。
            MultiBinding maxWidthBinding = new MultiBinding();

            Binding exFontSizeBinding = new Binding("ExFontSize");
            exFontSizeBinding.Source = editor;

            Binding wndWidthBinding = new Binding("ActualWidth");
            wndWidthBinding.Source = editor.BaseScrolledViewer;

            Binding indentBinding = new Binding("Indent");
            indentBinding.Source = this;

            Binding docAutoWrapBinding = new Binding("AutoWrap");
            docAutoWrapBinding.Source = editor;

            Binding selfAutoWrapBinding = new Binding("AutoWrap");
            selfAutoWrapBinding.Source = this;

            Binding maxTextWidthBinding = new Binding("MaxTextWidth");
            maxTextWidthBinding.Source = editor;

            maxWidthBinding.Bindings.Add(exFontSizeBinding);
            maxWidthBinding.Bindings.Add(wndWidthBinding);
            maxWidthBinding.Bindings.Add(indentBinding);
            maxWidthBinding.Bindings.Add(docAutoWrapBinding);
            maxWidthBinding.Bindings.Add(selfAutoWrapBinding);
            maxWidthBinding.Bindings.Add(maxTextWidthBinding);

            maxWidthBinding.Converter = Globals.maxWidthConverter;
            maxWidthBinding.ConverterParameter = this;

            BindingOperations.SetBinding(this, MaxWidthProperty, maxWidthBinding);
            #endregion

            #region 绑定字号
            MultiBinding textFontSizeLevelBinding = new MultiBinding();
            Binding fsBinding = new Binding("ExFontSize");
            fsBinding.Source = editor;

            Binding fslBinding = new Binding("FontSizeLevel");
            fslBinding.Source = this;

            textFontSizeLevelBinding.Bindings.Add(fsBinding);
            textFontSizeLevelBinding.Bindings.Add(fslBinding);

            textFontSizeLevelBinding.Converter = Globals.textFontSizeConverter;

            BindingOperations.SetBinding(this.textBlock,
                TextBox.FontSizeProperty, textFontSizeLevelBinding);
            #endregion

            this.IndentChanged += new EventHandler<IndentChangedEventArgs>(BaseText_IndentChanged);

            this.chineseName = "文本块";

            treeLineAdorner = new TreeLineAdorner(this.mainBorder, this);
            AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.mainBorder);
            adornerLayer.Add(treeLineAdorner);
        }

        void textBlock_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                if (this.Editor == null) return;

                this.Editor.SelectedExpression = this;
                Commands.Command.SelectInOrEdit();

                Globals.dragSourceExpression = null;// 防止出现鼠标动作过快时相互干扰。
                e.Handled = true;
            }
        }

        void BaseText_IndentChanged(object sender, IndentChangedEventArgs e)
        {
            if (this.ParentPanel == null) return;

            //考虑到撤销的需要，根据“IsHeaderText”判断是否要更改字号的代码不能放在此处。
            //也不能通过重写Indent属性来实现。
            //此一判断被放在Command.Outdent的相关方法中。

            this.ParentPanel.RefreshAutoNumbersOfBaseText();

            Globals.MainWindow.RefreshFontSizeLevel(FontSizeLevel);
        }

        private int autoNum = 0;

        /// <summary>
        /// 此一属性受制于“IsHeaderText”属性。
        /// 由所在子面板刷新其值。值由在子面板中的位置和Indent决定。
        /// Indent属性值变更时，会通知子面板处理。
        /// </summary>
        public int AutoNum
        {
            get { return autoNum; }
            set
            {
                autoNum = value;
                RefreshText();
            }
        }

        /// <summary>
        /// 用于备注。如果没有备注则此成员不会被实例化。
        /// </summary>
        private StackPanel basePanel = null;

        /// <summary>
        /// 同样用于备注。如果没有备注文本，此成员不会被实例化。
        /// </summary>
        private TextBlock commentTextBlock = null;

        public TextBlock CommentTextBlock
        {
            get { return commentTextBlock; }
        }

        private AdornerDecorator commentAdornerDecorator = null;

        public AdornerDecorator CommentAdornerDecorator
        {
            get { return commentAdornerDecorator; }
        }

        /// <summary>
        /// 也是用于备注。如果没有备注文本，此成员不会被实例化。
        /// </summary>
        private BaseTextCommentAdorner commentAdorner = null;

        public override string CommentText
        {
            get
            {
                return base.CommentText;
            }
            set
            {
                base.CommentText = value;
                RefreshCommentText();
            }
        }

        protected void RefreshCommentText()
        {
            if (commentText != null && commentText.Length > 0)
            {
                if (basePanel == null)
                {
                    this.basePanel = new StackPanel() { Orientation = Orientation.Vertical };
                    this.mainBorder.Child = this.basePanel;
                    this.basePanel.Children.Add(this.textBlock);
                }

                if (this.commentAdornerDecorator == null)
                {
                    this.commentAdornerDecorator = new AdornerDecorator();

                    Binding marginBinding = new Binding("FontSize");
                    marginBinding.Source = this.textBlock;
                    marginBinding.Converter = Globals.baseTextCommentIndentConverter;
                    this.commentAdornerDecorator.SetBinding(AdornerDecorator.MarginProperty, marginBinding);
                }

                if (this.commentTextBlock == null)
                {
                    this.commentTextBlock = new TextBlock()
                    {
                        Opacity = 0.75,
                        Foreground = this.textBlock.Foreground,
                        Padding = BaseText.textPadding,
                        TextWrapping = TextWrapping.Wrap,
                    };

                    Binding fontSizeBinding = new Binding("FontSize");
                    fontSizeBinding.Source = this.textBlock;
                    fontSizeBinding.Converter = Globals.baseTextCommentFontSizeConverter;
                    this.commentTextBlock.SetBinding(TextBox.FontSizeProperty, fontSizeBinding);

                    this.commentTextBlock.PreviewMouseDown += new MouseButtonEventHandler(commentTextBlock_PreviewMouseDown);
                    this.commentTextBlock.MouseEnter += new System.Windows.Input.MouseEventHandler(commentTextBox_MouseEnter);
                    this.commentTextBlock.MouseLeave += new System.Windows.Input.MouseEventHandler(commentTextBox_MouseLeave);

                    this.commentAdornerDecorator.Child = this.commentTextBlock;

                    this.basePanel.Children.Add(this.commentAdornerDecorator);
                }

                if (this.commentAdorner == null)
                {
                    this.commentAdorner = new BaseTextCommentAdorner(this.commentTextBlock);
                    this.commentAdorner.MouseEnter +=
                        new System.Windows.Input.MouseEventHandler(commentAdorner_MouseEnter);
                    this.commentAdorner.MouseLeave += new System.Windows.Input.MouseEventHandler(commentAdorner_MouseLeave);
                    this.commentAdornerDecorator.AdornerLayer.Add(this.commentAdorner);
                }

                this.commentTextBlock.Text = this.commentText.Replace((char)160, ' ').Replace(newSpace, "　");
            }
            else
            {
                if (this.basePanel != null)
                {
                    if (this.mainBorder.Child != this.textBlock &&
                        this.basePanel.Children.Contains(this.textBlock))
                    {
                        this.basePanel.Children.Remove(this.textBlock);
                        this.mainBorder.Child = this.textBlock;
                    }

                    if (this.commentTextBlock != null)
                    {
                        this.basePanel.Children.Remove(this.commentTextBlock);
                        this.commentTextBlock = null;
                    }

                    if (this.commentAdornerDecorator != null)
                    {
                        if (this.commentAdorner != null)
                        {
                            this.commentAdornerDecorator.AdornerLayer.Remove(this.commentAdorner);
                            this.commentAdorner = null;
                        }

                        this.commentAdornerDecorator = null;
                    }

                    this.basePanel = null;
                }
            }
        }

        void commentTextBlock_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                Commands.Command.Comment(Globals.MainWindow);
            }
        }

        void commentAdorner_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (this.commentTextBlock != null)
            {
                this.commentTextBlock.Opacity = 0.75;
            }

            this.commentAdorner.Opacity = 0.75;
        }

        void commentAdorner_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (this.commentTextBlock != null)
            {
                this.commentTextBlock.Opacity = 1.0;
            }

            this.commentAdorner.Opacity = 1.0;
        }

        void commentTextBox_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (this.commentAdorner != null)
            {
                this.commentAdorner.Opacity = 0.75;
            }

            commentTextBlock.Opacity = 0.75;
        }

        void commentTextBox_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (this.commentAdorner != null)
            {
                this.commentAdorner.Opacity = 1.0;
            }

            commentTextBlock.Opacity = 1.0;
        }

        private bool isHeaderText = false;

        /// <summary>
        /// 虽然从Indent和AutoNum已经可以判断一个文本块是否是标题。
        /// 但这无法判断这个文本块“本来是不是标题”。因此才有了这个属性。
        /// 用户在使用程序时，唯一可能修改此属性的时机是在设置文本块“样式”时。
        /// １－４级标题会令此属性值为真，其余（包括顶级标题、顶级副标题、正文）均为假。
        /// 在由正文返回４级标题所在的左缩进层级时，会根据此属性判断此文本块是否应自动
        /// 设置为４级标题。
        /// </summary>
        public bool IsHeaderText
        {
            get { return isHeaderText; }
            set
            {
                isHeaderText = value;

                this.XmlData.SetAttribute("IsHeaderText", isHeaderText.ToString());

                RefreshText();
                RefreshExForeground();

                this.editor.IsModified = true;

                if (isHeaderText)
                {
                    CreateCollapsedAdorner();
                }

                if (this.ParentPanel != null)
                {
                    this.ParentPanel.RefreshAutoNumbersOfBaseText();
                }
            }
        }

        private int semiAutoNum = 0;

        /// <summary>
        /// 半自动编号，由父面板调用。
        /// </summary>
        public int SemiAutoNum
        {
            private get { return semiAutoNum; }
            set
            {
                semiAutoNum = value;
                RefreshText();
            }
        }

        public void RefreshText()
        {
            if (isHeaderText && autoNum > 0)
            {
                textBlock.Text = AutoNumString + (showBackText ? backText : text);
            }
            else
            {
                //半自动编号时，父面板的RefreshAutoNumbersOfBaseText()方法将AutoNum为０。
                if (semiAutoNum > 0)
                {
                    textBlock.Text = semiAutoNum.ToString() + "〕" + (showBackText ? backText : text);
                }
                else
                {
                    textBlock.Text = showBackText ? backText : text;
                }
            }

            this.textBlock.InvalidateVisual();
        }

        public string AutoNumString
        {
            get
            {
                if (autoNum <= 0) return "";

                if (autoNum == 1)
                {
                    if (GetNextSameHeadLevelBaseText(this) == null)
                    {
                        switch (Indent)//标题一共只有四级。
                        {
                            case 0: return "◎ ";
                            case 1: return "● ";
                            case 2: return "◇ ";
                            default: return "◆ ";
                        }
                    }
                }

                switch (Indent)
                {
                    case 3:
                        {
                            return "(" + autoNum.ToString() + ")";
                        }
                    case 2:
                        {
                            return autoNum.ToString() + "．";
                        }
                    case 1:
                        {
                            return "(" + Globals.GetChineseNumber(autoNum) + ")";
                        }
                    case 0:
                        {
                            return Globals.GetChineseNumber(autoNum) + "、";
                        }
                    default:
                        {
                            return "";
                        }
                }
            }
        }

        /// <summary>
        /// 返回同缩进级的“上一个”文本块。
        /// </summary>
        public static Expressions.BaseText GetPreviewSameHeadLevelBaseText(BaseText bt)
        {
            if (bt.ParentPanel == null) return null;

            if (bt.ParentPanel.BasePanel.Children.Contains(bt) == false) return null;

            int index = bt.ParentPanel.BasePanel.Children.IndexOf(bt);

            for (int i = index - 1; i >= 0; i--)
            {
                if (bt.ParentPanel.BasePanel.Children[i] is BaseText == false) continue;

                BaseText preBt = bt.ParentPanel.BasePanel.Children[i] as BaseText;
                if (preBt.Indent > bt.Indent) continue;
                else if (preBt.Indent < bt.Indent)//目标是更靠左的标题。
                {
                    return null;
                }
                else
                {
                    if (preBt.IsHeaderText)
                    {
                        return preBt;
                    }
                    else return null;
                }
            }

            return null;
        }

        /// <summary>
        /// 返回同缩进级的“下一个”文本块。
        /// </summary>
        public static Expressions.BaseText GetNextSameHeadLevelBaseText(BaseText bt)
        {
            if (bt.ParentPanel == null) return null;

            if (bt.ParentPanel.BasePanel.Children.Contains(bt) == false) return null;

            int index = bt.ParentPanel.BasePanel.Children.IndexOf(bt);

            for (int i = index + 1; i < bt.ParentPanel.BasePanel.Children.Count; i++)
            {
                //if (bt.ParentPanel.BasePanel.Children[i] is BaseText == false) continue;

                BaseText nextBt = bt.ParentPanel.BasePanel.Children[i] as BaseText;

                if (nextBt == null) continue;

                if (nextBt.Indent > bt.Indent) continue;
                else if (nextBt.Indent < bt.Indent)//目标是更靠左的标题。
                {
                    return null;
                }
                else
                {
                    if (nextBt.IsHeaderText)
                    {
                        return nextBt;
                    }
                    else continue;
                }
            }

            return null;
        }

        void textBox_MouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            this.Editor.SelectedExpression = this;
            e.Handled = true;
        }

        void textBox_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            textBlock.Background = Brushes.Transparent;
            mainBorder.Background = ExBackground;
            //textBlock.BorderBrush = Brushes.Transparent;
            SelectAdorner.InvalidateVisual();
        }

        void textBox_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            textBlock.Background = Globals.baseActiveBackGround;
            //textBlock.BorderBrush = Brushes.White;
            SelectAdorner.InvalidateVisual();
        }

        /// <summary>
        /// 实现拖放。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void textBox_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Globals.DropExpression(this);
        }

        void textBox_MouseLeftButtonDown(object sender,
            System.Windows.Input.MouseButtonEventArgs e)
        {
            if (Globals.BaseTextFormatBrush != null &&
                Globals.BaseTextFormatBrush.SourceExID != this.ExID)
            {
                string className = this.GetType().Name;
                ModifingItem mi = new ModifingItem() { AutoNumPanelID = this.ParentPanel.ExID };
                Action act1 = new Action(this.ExID, -1, className, "StrikeLine",
                    this.StrikeLine.ToString(), Globals.BaseTextFormatBrush.StrikeLine.ToString());
                this.StrikeLine = Globals.BaseTextFormatBrush.StrikeLine;

                Action act2 = new Action(this.ExID, -1, className, "UnderLine",
                    this.UnderLine.ToString(), Globals.BaseTextFormatBrush.UnderLine.ToString());
                this.UnderLine = Globals.BaseTextFormatBrush.UnderLine;

                //Action act3 = new Action(this.ExID, -1, className, "TextBackground",
                //    ColorPicker.GetBrushName(this.TextBackground),
                //    ColorPicker.GetBrushName(Globals.FormatBrush.TextBackground));
                //this.TextBackground = Globals.FormatBrush.TextBackground;

                Action act3 = new Action(this.ExID, -1, className, "ExBackground",
                    ColorPicker.GetBrushName(this.ExBackground),
                    ColorPicker.GetBrushName(Globals.BaseTextFormatBrush.ExBackground));
                this.ExBackground = Globals.BaseTextFormatBrush.ExBackground;

                Action act4;
                if (Globals.BaseTextFormatBrush.ExForeground == null)
                {
                    act4 = new Action(this.ExID, -1, className, "ExForeground",
                        ColorPicker.GetBrushName(this.exForeground), null);
                    XmlAttribute attrForeground = this.XmlData.GetAttribute("ExForeground");
                    if (attrForeground != null)
                    {
                        this.XmlData.Attributes.Remove(attrForeground);
                    }
                }
                else
                {
                    act4 = new Action(this.ExID, -1, className, "ExForeground",
                        ColorPicker.GetBrushName(this.ExForeground),
                        ColorPicker.GetBrushName(Globals.BaseTextFormatBrush.ExForeground));
                    this.ExForeground = Globals.BaseTextFormatBrush.ExForeground;
                }

                Action act5 = new Action(this.ExID, -1, className, "Indent",
                    this.Indent.ToString(), Globals.BaseTextFormatBrush.Indent.ToString());
                this.Indent = Globals.BaseTextFormatBrush.Indent;

                Action act6 = new Action(this.ExID, -1, className, "FontName",
                    this.FontName, Globals.BaseTextFormatBrush.FontName);
                this.FontName = Globals.BaseTextFormatBrush.FontName;

                Action act7 = new Action(this.ExID, -1, className, "BorderColor",
                    ColorPicker.GetBrushName(this.BorderColor),
                    ColorPicker.GetBrushName(Globals.BaseTextFormatBrush.BorderBrush));
                this.BorderColor = Globals.BaseTextFormatBrush.BorderBrush;

                Action act8 = new Action(this.ExID, -1, className, "BorderWidth",
                    this.BorderWidth.ToString(), Globals.BaseTextFormatBrush.BorderWidth.ToString());
                this.BorderWidth = Globals.BaseTextFormatBrush.BorderWidth;

                Action act9 = new Action(this.ExID, -1, className, "FontStyle",
                    this.FontStyle.ToString(), Globals.BaseTextFormatBrush.FontStyle.ToString());
                this.FontStyle = Globals.BaseTextFormatBrush.FontStyle;

                Action act10 = new Action(this.ExID, -1, className, "FontWeight",
                    this.FontWeight.ToString(), Globals.BaseTextFormatBrush.FontWeight.ToString());
                this.FontWeight = Globals.BaseTextFormatBrush.FontWeight;

                Action act11 = new Action(this.ExID, -1, className, "FontSizeLevel",
                    this.FontSizeLevel.ToString(), Globals.BaseTextFormatBrush.FontSizeLevel.ToString());
                this.FontSizeLevel = Globals.BaseTextFormatBrush.FontSizeLevel;

                Action act12 = new Action(this.ExID, -1, className, "Align",
                    this.Align.ToString(), Globals.BaseTextFormatBrush.Align.ToString());
                this.Align = Globals.BaseTextFormatBrush.Align;

                if (ParentPanel != null)
                {
                    ParentPanel.RefreshAutoNumbersOfBaseText();//注意顺序。
                    ParentPanel.RefreshTreeLinesOfHeaderText();//可能不会引发父面板的SizeChanged事件。因此需要手工调用。
                }

                Action act13 = new Action(this.ExID, -1, className, "IsHeaderText",
                    this.IsHeaderText.ToString(), Globals.BaseTextFormatBrush.IsHeaderText.ToString());
                this.IsHeaderText = Globals.BaseTextFormatBrush.IsHeaderText;

                //遮罩
                Action act14 = new Action(this.ExID, -1, className, "Mask",
                    this.Mask.ToString(), Globals.BaseTextFormatBrush.Mask.ToString());
                this.Mask = Globals.BaseTextFormatBrush.Mask;

                mi.Add(act1); mi.Add(act2); mi.Add(act3); mi.Add(act4); mi.Add(act5);
                mi.Add(act6); mi.Add(act7); mi.Add(act8); mi.Add(act9); mi.Add(act10);
                mi.Add(act11); mi.Add(act12); mi.Add(act13); mi.Add(act14);

                Editor.Do(mi);

                Editor.SelectedExpression = this;

                this.RefreshExForeground();

                //重复了。
                //if (this.ParentPanel != null)
                //{
                //    this.ParentPanel.RefreshAutoNumbersOfBaseText();
                //}

                if (Globals.BaseTextFormatBrush.IsMuiltFormatBrush == false)
                {
                    Globals.MainWindow.tbtnFormatBrush.IsChecked = false;
                    Globals.BaseTextFormatBrush = null;
                    e.Handled = true;
                    return;
                }
            }

            this.Editor.SelectedExpression = this;

            //准备拖动公式。
            Globals.dragSourceExpression = this;
            e.Handled = true;
        }

        private TextBlock textBlock;

        public TextBlock TextBlock
        {
            get { return textBlock; }
        }

        public override Brush ExForeground
        {
            get
            {
                return base.ExForeground;
            }
            set
            {
                UpdateExForegroundWithoutXmlChanging(value);
                UpdateExForegroundToXmlData(value);

                //刷新下划线与删除线的色彩。

                foreach (TextDecoration td in this.textBlock.TextDecorations)
                {
                    if (td.Location == TextDecorationLocation.Underline ||
                        td.Location == TextDecorationLocation.Strikethrough)
                    {
                        td.Pen.Brush = exForeground;
                    }
                }
                Editor.IsModified = true;
            }
        }

        public override void UpdateExForegroundWithoutXmlChanging(Brush value)
        {
            base.UpdateExForegroundWithoutXmlChanging(value);

            base.exForeground = value;
            this.textBlock.Foreground = value;

            if (this.underLine || this.strikeLine)
            {
                this.textBlock.TextDecorations.Clear();
                if (this.underLine)
                {
                    SetUnderline(this.underLine);
                }

                if (this.strikeLine)
                {
                    SetStrikeLine(this.strikeLine);
                }
            }

            if (this.commentTextBlock != null)
            {
                this.commentTextBlock.Foreground = value;
            }

            if (this.commentAdorner != null)
            {
                this.commentAdorner.InvalidateVisual();
            }

            if (this.maskAdorner != null)
            {
                this.maskAdorner.InvalidateVisual();
            }

            if (this.collpasedAdorner != null)
            {
                this.collpasedAdorner.InvalidateVisual();
            }

            if (this.indentAdorner != null)
            {
                this.indentAdorner.InvalidateVisual();
            }

            this.treeLineAdorner.InvalidateVisual();
        }

        private bool showBackText = false;

        /// <summary>
        /// 是否显示后台文本。
        /// </summary>
        public bool ShowBackText
        {
            get { return showBackText; }
            set
            {
                if (showBackText != value)
                {
                    showBackText = value;
                    this.XmlData.SetAttribute("ShowBackText", value.ToString());

                    RefreshText();

                    this.Editor.IsModified = true;
                }
            }
        }

        /// <summary>
        /// 此属性并非多余。因为存在后台文本。
        /// </summary>
        private string text = "";

        /// <summary>
        /// 文本块的文本。
        /// </summary>
        public String Text
        {
            get { return text; }
            set
            {
                this.text = value;

                // 向后台写入xml数据。
                XmlNode textNode = this.XmlData.SelectSingleNode("Text");
                if (textNode != null)
                {
                    textNode.InnerText = value;
                }
                else
                {
                    MessageBox.Show("未找到“Text”节点，无法修改文本块内容文本！",
                        Globals.appName, MessageBoxButton.OK,
                        MessageBoxImage.Warning);
                }

                RefreshText();

                this.Editor.IsModified = true;
            }
        }

        private string backText = "..<默认后台文本>..";

        public string BackText
        {
            get { return backText; }
            set
            {
                if (backText != value)
                {
                    backText = value;

                    XmlNode backTextNode = this.XmlData.SelectSingleNode("BackText");
                    if (backTextNode != null)
                    {
                        backTextNode.InnerText = value;

                        if (this.showBackText)
                        {
                            RefreshText();
                        }

                        this.Editor.IsModified = true;
                    }
                    else
                    {
                        XmlNode textNode = this.XmlData.SelectSingleNode("Text");
                        if (textNode != null)
                        {
                            textNode.InsertXml("<BackText>" + value + "</BackText>");

                            if (this.showBackText)
                            {
                                RefreshText();
                            }

                            this.Editor.IsModified = true;
                        }
                        else
                        {
                            this.XmlData.InnerXml = "<BackText>" + value + "</BackText>";

                            if (this.showBackText)
                            {
                                RefreshText();
                            }

                            this.Editor.IsModified = true;
                        }
                    }
                }
            }
        }

        private static readonly Thickness textPadding = new Thickness(5, 3, 5, 3);

        //纠正过去的错误做法。
        private static char[] spaces = new char[2] { (char)160, (char)160 };
        private static string newSpace = new string(spaces);

        protected override void BuildChildren()
        {
            base.BuildChildren();

            RefreshCommentText();

            if (this.XmlData == null) return;

            if (this.textBlock == null)
            {
                this.textBlock = new TextBlock() { Padding = BaseText.textPadding, TextWrapping = TextWrapping.Wrap };
                this.Child = this.textBlock;
            }

            #region 读取文本

            //纠正过去的错误做法。
            //char[] spaces = new char[2] { (char)160, (char)160 };
            //string newSpace = new string(spaces);

            //string tmp = bte.inputTextBox.Text.Replace((char)160, ' ');
            //string resultString = tmp.Replace(newSpace, "　");

            XmlNode textNode = this.XmlData.SelectSingleNode("Text");
            if (textNode != null)
            {
                this.text = textNode.InnerText.Replace((char)160, ' ').Replace(newSpace, "　");
            }

            XmlNode backTextNode = this.XmlData.SelectSingleNode("BackText");
            if (backTextNode != null)
            {
                backText = backTextNode.Value.Replace((char)160, ' ').Replace(newSpace, "　");
            }

            XmlAttribute showBackTextAttr = this.XmlData.GetAttribute("ShowBackText");
            if (showBackTextAttr != null && bool.Parse(showBackTextAttr.Value) == true)
            {
                showBackText = true;
                this.textBlock.Text = backText;
            }
            else
            {
                showBackText = false;
                this.textBlock.Text = text;
            }
            #endregion

            XmlAttribute attrAutoWrap = this.XmlData.GetAttribute("AutoWrap");
            if (attrAutoWrap != null)
            {
                try
                {
                    this.AutoWrap = (AutoWrapType)Enum.Parse(typeof(AutoWrapType), attrAutoWrap.Value);
                }
                catch (Exception ex)
                {
                    Dialogs.LunarMsgBox.MsgBoxShow(
                        Globals.appName,
                        "意外错误，文本块读取到的“自动折行”值非法。",
                        "异常信息如下：\r\n" + ex.Message,
                        ex.StackTrace, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
            }

            XmlAttribute attrFontName = XmlData.GetAttribute("FontName");
            if (attrFontName != null)
            {
                this.fontName = attrFontName.Value;
                this.textBlock.FontFamily = new FontFamily(attrFontName.Value);
            }

            XmlAttribute attrFontWeight = XmlData.GetAttribute("FontWeight");
            if (attrFontWeight != null)
            {
                this.fontWeight = GetFontWeightFromString(attrFontWeight.Value);
                this.textBlock.FontWeight = this.fontWeight;
            }

            XmlAttribute attrFontStyle = XmlData.GetAttribute("FontStyle");
            if (attrFontStyle != null)
            {
                this.fontStyle = GetFontStyleFromString(attrFontStyle.Value);
                this.textBlock.FontStyle = this.fontStyle;
            }

            XmlAttribute attrUnderLine = XmlData.GetAttribute("UnderLine");
            if (attrUnderLine != null)
            {
                this.underLine = Boolean.Parse(attrUnderLine.Value);
                SetUnderline(this.underLine);
            }

            XmlAttribute attrStrikeLine = XmlData.GetAttribute("StrikeLine");
            if (attrStrikeLine != null)
            {
                this.strikeLine = Boolean.Parse(attrStrikeLine.Value);
                SetStrikeLine(this.strikeLine);
            }

            XmlAttribute attrFontSizeLevel = XmlData.GetAttribute("FontSizeLevel");
            if (attrFontSizeLevel != null)
            {
                this.fontSizeLevel = int.Parse(attrFontSizeLevel.Value);
                OnPropertyChanged(this, new PropertyChangedEventArgs("FontSizeLevel"));
            }

            XmlAttribute attrIsHeaderText = XmlData.GetAttribute("IsHeaderText");
            if (attrIsHeaderText != null)
            {
                this.isHeaderText = bool.Parse(attrIsHeaderText.Value);
            }

            XmlAttribute attrIsCollapsed = this.XmlData.GetAttribute("IsCollapsed");
            if (attrIsCollapsed != null)
            {
                this.isCollapsed = bool.Parse(attrIsCollapsed.Value);
                this.RefreshIsCollapsed();
            }

            XmlAttribute attrShowTreeLine = this.XmlData.GetAttribute("ShowTreeLine");
            if (attrShowTreeLine != null)
            {
                this.showTreeLine = bool.Parse(attrShowTreeLine.Value);
                this.RefreshTreeLine();
            }

            XmlAttribute attrMask = this.XmlData.GetAttribute("Mask");
            if (attrMask != null)
            {
                try
                {
                    MaskType mt = (MaskType)Enum.Parse(typeof(MaskType), attrMask.Value);
                    if (mt != MaskType.None)
                    {
                        this.mask = mt;
                        this.RefreshMask();
                    }
                }
                catch (Exception ex)
                {
                    Dialogs.LunarMsgBox.MsgBoxShow(
                        Globals.appName,
                        "意外错误，文本块读取到的“遮罩”值非法。",
                        "异常信息如下：\r\n" + ex.Message,
                        ex.StackTrace, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
            }

            XmlAttribute attrTaskItemType = this.XmlData.GetAttribute("TaskItemType");
            if (attrTaskItemType != null)
            {
                try
                {
                    this.taskItemType = (TaskType)Enum.Parse(typeof(TaskType), attrTaskItemType.Value);
                    RefreshTaskItemType(this.taskItemType);
                }
                catch (Exception ex)
                {
                    Dialogs.LunarMsgBox.MsgBoxShow(
                        Globals.appName,
                        "意外错误，文本块读取到的“任务列表项类型”值非法。",
                        "异常信息如下：\r\n" + ex.Message,
                        ex.StackTrace, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
            }

            RefreshExForeground();
        }

        public override int Indent
        {
            get
            {
                return base.Indent;
            }
            set
            {
                base.Indent = value;
                RefreshExForeground();
            }
        }

        public void RefreshExForeground()
        {
            if (Editor != null)
            {
                XmlAttribute attrForeground = this.XmlData.GetAttribute("ExForeground");
                if (attrForeground == null)
                {
                    if (isHeaderText)
                    {
                        switch (this.Indent)
                        {
                            case 0:
                                {
                                    UpdateExForegroundWithoutXmlChanging(Editor.DefHeaderText1Brush); break;
                                }
                            case 1:
                                {
                                    UpdateExForegroundWithoutXmlChanging(Editor.DefHeaderText2Brush); break;
                                }
                            case 2:
                                {
                                    UpdateExForegroundWithoutXmlChanging(Editor.DefHeaderText3Brush); break;
                                }
                            case 3:
                                {
                                    UpdateExForegroundWithoutXmlChanging(Editor.DefHeaderText4Brush); break;
                                }
                            default:
                                {
                                    UpdateExForegroundWithoutXmlChanging(Editor.DefaultForeground); break;
                                }
                        }
                    }
                    else
                    {
                        UpdateExForegroundWithoutXmlChanging(Editor.DefaultForeground);
                    }
                }
                else
                {
                    UpdateExForegroundWithoutXmlChanging(ColorPicker.GetBrushByName(attrForeground.Value));
                }
            }
        }

        private string fontName = Globals.SysFontFamily;

        public string FontName
        {
            get { return fontName; }
            set
            {
                if (fontName != value && value.Length > 0)
                {
                    fontName = value;
                    this.textBlock.FontFamily = new FontFamily(fontName);
                    if (this.XmlData != null)
                    {
                        this.XmlData.SetAttribute("FontName", fontName);
                    }
                    Editor.IsModified = true;
                }
            }
        }

        private FontWeight fontWeight = FontWeights.Normal;

        public FontWeight FontWeight
        {
            get { return fontWeight; }
            set
            {
                fontWeight = value;
                if (this.XmlData != null)
                {
                    this.XmlData.SetAttribute("FontWeight", fontWeight.ToString());
                }

                this.textBlock.FontWeight = fontWeight;
                Editor.IsModified = true;
            }
        }

        private FontStyle fontStyle = FontStyles.Normal;

        public FontStyle FontStyle
        {
            get { return fontStyle; }
            set
            {
                fontStyle = value;
                if (this.XmlData != null)
                {
                    this.XmlData.SetAttribute("FontStyle", fontStyle.ToString());
                }

                this.textBlock.FontStyle = fontStyle;
                Editor.IsModified = true;
            }
        }

        public static FontWeight GetFontWeightFromString(string fontWeightString)
        {
            switch (fontWeightString)
            {
                case "Bold": return FontWeights.Bold;
                default: return FontWeights.Normal;// 目前只支持两种。
            }
        }

        public static FontStyle GetFontStyleFromString(string fontStyleString)
        {
            switch (fontStyleString)
            {
                case "Italic": return FontStyles.Italic;
                default: return FontStyles.Normal;// 目前只支持两种。
            }
        }

        private bool underLine = false;

        public bool UnderLine
        {
            get { return underLine; }
            set
            {
                underLine = value;
                if (this.XmlData != null)
                {
                    this.XmlData.SetAttribute("UnderLine", underLine.ToString());
                }
                SetUnderline(underLine);
                Editor.IsModified = true;
            }
        }

        private bool strikeLine = false;

        public bool StrikeLine
        {
            get { return strikeLine; }
            set
            {
                strikeLine = value;
                if (this.XmlData != null)
                {
                    this.XmlData.SetAttribute("StrikeLine", strikeLine.ToString());
                }
                SetStrikeLine(strikeLine);
                Editor.IsModified = true;
            }
        }

        private void SetUnderline(bool underLine)
        {
            if (underLine)
            {
                TextDecoration myLine = new TextDecoration();
                // 为text decoration创建一个画笔。
                Pen myPen = new Pen();
                //myPen.Brush = Brushes.White;
                myPen.Brush = this.exForeground;
                //new LinearGradientBrush(Colors.Yellow, Colors.Red, new Point(0, 0.5), new Point(1, 0.5));
                //myPen.Brush.Opacity = 0.5;
                myPen.Thickness = 1;
                //myPen.DashStyle = DashStyles.Dash;
                myLine.Pen = myPen;
                myLine.PenThicknessUnit = TextDecorationUnit.FontRecommended;

                myLine.Location = System.Windows.TextDecorationLocation.Underline;

                this.textBlock.TextDecorations.Add(myLine);
            }
            else
            {
                for (int i = this.textBlock.TextDecorations.Count - 1; i >= 0; i--)
                {
                    if (this.textBlock.TextDecorations[i].Location == System.Windows.TextDecorationLocation.Underline)
                    {
                        this.textBlock.TextDecorations.RemoveAt(i);
                    }
                }
            }
        }

        private void SetStrikeLine(bool strikeLine)
        {
            if (strikeLine)
            {
                TextDecoration myLine = new TextDecoration();
                // 为text decoration创建一个画笔。
                Pen myPen = new Pen();
                myPen.Brush = this.exForeground;
                //new LinearGradientBrush(Colors.Yellow, Colors.Red, new Point(0, 0.5), new Point(1, 0.5));
                //myPen.Brush.Opacity = 0.5;
                myPen.Thickness = 1.2;
                //myPen.DashStyle = DashStyles.Dash;
                myLine.Pen = myPen;
                myLine.PenThicknessUnit = TextDecorationUnit.FontRecommended;
                myLine.Location = System.Windows.TextDecorationLocation.Strikethrough;

                this.textBlock.TextDecorations.Add(myLine);
            }
            else
            {
                for (int i = this.textBlock.TextDecorations.Count - 1; i >= 0; i--)
                {
                    if (this.textBlock.TextDecorations[i].Location == System.Windows.TextDecorationLocation.Strikethrough)
                    {
                        this.textBlock.TextDecorations.RemoveAt(i);
                    }
                }
            }

        }

        /// <summary>
        /// 字号缩放等级。
        /// </summary>
        private int fontSizeLevel = 0;

        public int FontSizeLevel
        {
            get { return fontSizeLevel; }
            set
            {
                if (value >= 0 && value <= 6)
                {
                    fontSizeLevel = value;
                    this.XmlData.SetAttribute("FontSizeLevel", value.ToString());

                    OnPropertyChanged(this, new PropertyChangedEventArgs("FontSizeLevel"));
                }
            }
        }

        #region “撤销”与“重做”。

        /// <summary>
        /// 这个方法是重头戏。必须列出本类型公式支持的所有“可修改”属性。
        /// </summary>
        /// <param name="propertyName"></param>
        /// <param name="value"></param>
        public override void SetProperty(string propertyName, string value)
        {
            base.SetProperty(propertyName, value);

            switch (propertyName)
            {
                case "Text":
                    {
                        this.Text = value;
                        break;
                    }
                case "BackText":
                    {
                        this.BackText = value;
                        break;
                    }
                case "ShowBackText":
                    {
                        this.ShowBackText = bool.Parse(value);
                        break;
                    }
                case "StrikeLine":
                    {
                        this.StrikeLine = bool.Parse(value);
                        break;
                    }
                case "UnderLine":
                    {
                        this.UnderLine = bool.Parse(value);
                        break;
                    }
                case "FontName":
                    {
                        this.FontName = value; break;
                    }
                case "FontStyle":
                    {
                        switch (value)
                        {
                            case "Italic":
                                {
                                    this.FontStyle = FontStyles.Italic;
                                    this.Editor.ParentWindow.tbtnItalic.IsChecked = true;
                                    break;
                                }
                            default:
                                {
                                    this.FontStyle = FontStyles.Normal;
                                    this.Editor.ParentWindow.tbtnItalic.IsChecked = false;
                                    break;
                                }
                        }
                        break;
                    }
                case "FontWeight":
                    {
                        switch (value)
                        {
                            case "Bold":
                                {
                                    this.FontWeight = FontWeights.Bold;
                                    this.Editor.ParentWindow.tbtnBold.IsChecked = true;
                                    break;
                                }
                            default:
                                {
                                    this.FontWeight = FontWeights.Normal;
                                    this.Editor.ParentWindow.tbtnBold.IsChecked = false;
                                    break;
                                }
                        }
                        break;
                    }
                case "FontSizeLevel":
                    {
                        this.FontSizeLevel = int.Parse(value);
                        break;
                    }
                case "IsHeaderText":
                    {
                        this.IsHeaderText = bool.Parse(value);
                        break;
                    }
                case "IsCollapsed":
                    {
                        this.IsCollapsed = bool.Parse(value);
                        break;
                    }
                case "ShowTreeLine":
                    {
                        this.ShowTreeLine = bool.Parse(value);
                        break;
                    }
                case "Mask":
                    {
                        try
                        {
                            this.Mask = (MaskType)Enum.Parse(typeof(MaskType), value);
                        }
                        catch (Exception ex)
                        {
                            Dialogs.LunarMsgBox.MsgBoxShow(
                                Globals.appName,
                                "意外错误，文本块读取到的“遮罩”值非法。",
                                "异常信息如下：\r\n" + ex.Message,
                                ex.StackTrace, MessageBoxButton.OK, MessageBoxImage.Warning);
                        }
                        break;
                    }
                case "TaskItemType":
                    {
                        try
                        {
                            this.TaskItemType = (TaskType)Enum.Parse(typeof(TaskType), value);
                        }
                        catch (Exception ex)
                        {
                            Dialogs.LunarMsgBox.MsgBoxShow(
                                Globals.appName,
                                "意外错误，文本块读取到的“任务列表项类型”值非法。",
                                "异常信息如下：\r\n" + ex.Message, ex.StackTrace,
                                MessageBoxButton.OK, MessageBoxImage.Warning);
                        }
                        break;
                    }
                case "AutoWrap":
                    {
                        try
                        {
                            this.AutoWrap = (AutoWrapType)Enum.Parse(typeof(AutoWrapType), value);
                        }
                        catch (Exception ex)
                        {
                            Dialogs.LunarMsgBox.MsgBoxShow(
                                Globals.appName,
                                "意外错误，文本块读取到的“自动折行类型”值非法。",
                                "异常信息如下：\r\n" + ex.Message,
                                ex.StackTrace, MessageBoxButton.OK, MessageBoxImage.Warning);
                        }
                        break;
                    }
                case "ExForeground":
                    {
                        if (value == null)
                        {
                            XmlAttribute attrForeground = this.XmlData.GetAttribute("ExForeground");
                            if (attrForeground != null)
                            {
                                this.XmlData.Attributes.Remove(attrForeground);
                            }

                            this.RefreshExForeground();
                        }
                        else
                        {
                            this.ExForeground = ColorPicker.GetBrushByName(value);
                        }
                        break;
                    }
                //default:
                //    {
                //        MessageBox.Show("未找到属性：" + propertyName, Globals.appName,
                //            MessageBoxButton.OK, MessageBoxImage.Warning);
                //        break;
                //    }
                //TODO :完成BaseText的其它部分。
            }
        }
        #endregion

        private bool isCollapsed = false;

        /// <summary>
        /// 与其它公式不同，标题文本块才支持的折叠，
        /// 影响的不是自身，而是与标题文本块在同一子面板内的“下级”公式。
        /// </summary>
        public bool IsCollapsed
        {
            get
            {
                return isCollapsed;
            }
            set
            {
                if (this.isHeaderText == false)
                {
                    MessageBox.Show("当前文本块不是四级普通标题中的任何一级！“折叠”操作无意义！",
                        Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                if (this.Indent >= 4)
                {
                    MessageBox.Show("当前文本块缩进级别过大！“折叠”操作无意义！\r\n" +
                        "标题文本块只有在前四个缩进级别（含０级）才有效！",
                        Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                List<Expressions.Expression> subIndentExpressions = this.GetSubIndentExpressions();

                if (subIndentExpressions == null || subIndentExpressions.Count <= 0)//注意，前一个用属性，后一个用字段。
                {
                    MessageBox.Show("当前文本块没有“下级”公式，“折叠”操作没有意义。",
                           Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                if (ParentPanel != null && this.XmlData != null)
                {
                    isCollapsed = value;

                    if (isCollapsed)
                    {
                        this.ToolTip = "折叠文本块>禁止以下操作：\r\n　剪切｜复制｜粘贴｜删除\r\n　平移｜缩进｜对齐｜嵌入";
                    }
                    else
                    {
                        this.ToolTip = null;
                    }

                    this.XmlData.SetAttribute("IsCollapsed", value.ToString());

                    RefreshIsCollapsed();

                    Editor.IsModified = true;
                }

                RefreshTreeLine();
            }
        }

        private bool showTreeLine = false;

        /// <summary>
        /// 是否显示树型连线。此属性受制于“isHeaderText”、“isCollapsed”。
        /// ——即使此属性值为真也不一定显示树型连线。
        /// </summary>
        public bool ShowTreeLine
        {
            get { return showTreeLine; }
            set
            {
                showTreeLine = value;
                if (this.XmlData != null)
                {
                    this.XmlData.SetAttribute("ShowTreeLine", value.ToString());
                }

                RefreshTreeLine();
                Editor.IsModified = true;
            }
        }

        public void RefreshTreeLine()
        {
            this.treeLineAdorner.InvalidateVisual();
        }

        private TreeLineAdorner treeLineAdorner = null;

        private CollapsedAdorner collpasedAdorner = null;

        /// <summary>
        /// 与括弧式等其它公式不同。这个方法除了自身调用之外，
        /// 还得由子面板调用（在子面板的BuildChildren()方法末尾)。
        /// 这样才能保证读取文件时折叠状态准确。
        /// </summary>
        public void RefreshIsCollapsed()
        {
            if (this.ParentPanel != null && this.isHeaderText && this.Indent <= 3)
            {
                List<Expressions.Expression> subExs = this.GetSubIndentExpressions();

                if (subExs != null && subExs.Count > 0)
                {
                    //tag的值表示当前标题是否拥有管辖权。
                    foreach (Expressions.Expression iEx in subExs)
                    {
                        iEx.jurisdiction = true;
                    }

                    for (int i = 0; i < subExs.Count; i++)
                    {
                        //检查每一个公式是否在本标题的管辖范围内。
                        Expressions.Expression ex = subExs[i];
                        if (ex is Expressions.BaseText)
                        {
                            Expressions.BaseText iBt = ex as Expressions.BaseText;
                            if (iBt.IsHeaderText && iBt.IsCollapsed)
                            {
                                List<Expressions.Expression> iSubExs = iBt.GetSubIndentExpressions();
                                if (iSubExs != null && iSubExs.Count > 0)
                                {
                                    foreach (Expressions.Expression iiEx in iSubExs)
                                    {
                                        iiEx.jurisdiction = false;
                                    }
                                }
                            }
                        }
                    }

                    for (int i = 0; i < subExs.Count; i++)
                    {
                        Expression ex = subExs[i];
                        if (ex.jurisdiction == true)//如果拥有管辖权，才由本公式直接处置。
                        {
                            ex.Visibility = isCollapsed ? Visibility.Collapsed : Visibility.Visible;
                        }
                    }
                }
            }

            CreateCollapsedAdorner();
        }

        /// <summary>
        /// 将一个文本块设置为标题（1－4级）时，需要调用此方法，以立即显示折叠标记。
        /// ——尽管此时很可能因为没有管辖的“下级公式”而使折叠标记处于不可用状态。
        /// </summary>
        private void CreateCollapsedAdorner()
        {
            if (isHeaderText && Indent <= 3)
            {
                if (this.collpasedAdorner == null)
                {
                    this.collpasedAdorner = new CollapsedAdorner(this);
                    AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.mainBorder);
                    adornerLayer.Add(this.collpasedAdorner);
                }
                else
                {
                    AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.mainBorder);
                    adornerLayer.Remove(this.collpasedAdorner);
                    adornerLayer.Add(this.collpasedAdorner);
                    this.collpasedAdorner.Visibility = Visibility.Visible;
                }
            }
            else
            {
                if (this.collpasedAdorner != null)
                {
                    this.collpasedAdorner.Visibility = Visibility.Hidden;
                }
            }
        }

        /// <summary>
        /// 返回当前标题文本块的“下级”公式的集合。
        /// 如果当前文本块不是标题文本，则返回null。
        /// 任意一个左缩进级别小于等于本标题文本块的公式均不是“下级公式”，
        /// 无论此公式是否文本块，更不管此公式是否标题。——这里只论缩进，看起来自然得多。
        /// </summary>
        public List<Expression> GetSubIndentExpressions()
        {
            if (isHeaderText == false) return null;

            if (this.ParentPanel != null)
            {
                List<Expressions.Expression> subIndentExpressions = new List<Expression>();

                for (int i = this.ParentPanel.BasePanel.Children.IndexOf(this) + 1;
                    i < this.ParentPanel.BasePanel.Children.Count; i++)
                {
                    Expression ex = this.ParentPanel.BasePanel.Children[i] as Expression;
                    if (ex.Indent <= this.Indent) break;

                    subIndentExpressions.Add(ex);
                }

                return subIndentExpressions;
            }

            return null;
        }

        private MaskAdorner maskAdorner;

        /// <summary>
        /// Bias是斜线。
        /// </summary>
        public enum MaskType { None, HLine, VLine, HVLine, LeftBias, RightBias }

        private MaskType mask = MaskType.None;

        /// <summary>
        /// 文本块遮罩。
        /// </summary>
        public MaskType Mask
        {
            get { return mask; }
            set
            {
                mask = value;

                if (this.XmlData != null)
                {
                    this.XmlData.SetAttribute("Mask", mask.ToString());
                }

                RefreshMask();
            }
        }

        private void RefreshMask()
        {
            switch (mask)
            {
                case MaskType.None:
                    {
                        if (this.maskAdorner != null)
                        {
                            this.maskAdorner.Visibility = Visibility.Collapsed;
                        }
                        break;
                    }
                default:
                    {
                        if (this.maskAdorner == null)
                        {
                            this.maskAdorner = new MaskAdorner(this);
                            this.maskAdorner.MouseLeftButtonDown += new MouseButtonEventHandler(maskAdorner_MouseLeftButtonDown);
                            AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.mainBorder);
                            adornerLayer.Add(this.maskAdorner);
                        }
                        else
                        {
                            this.maskAdorner.Visibility = Visibility.Visible;
                            this.maskAdorner.InvalidateVisual();
                        }
                        break;
                    }
            }

            //防止折叠装饰器失效。
            if (this.collpasedAdorner != null)
            {
                AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.mainBorder);
                adornerLayer.Remove(this.collpasedAdorner);
                adornerLayer.Add(this.collpasedAdorner);
            }
        }

        void maskAdorner_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            textBox_MouseLeftButtonDown(sender, e);
            e.Handled = true;
        }

        /// <summary>
        /// 将文本块作为任务列表项。
        /// </summary>
        public enum TaskType { NotTask, NotStarted, Running, Aborted, Finished, Paused }

        private TaskType taskItemType = TaskType.NotTask;

        public TaskType TaskItemType
        {
            get { return taskItemType; }
            set
            {
                taskItemType = value;
                RefreshTaskItemType(value);

                this.XmlData.SetAttribute("TaskItemType", value.ToString());
            }
        }

        private void RefreshTaskItemType(TaskType taskType)
        {
            OnPropertyChanged(this, new PropertyChangedEventArgs("TaskItemType"));
            if (this.indentAdorner != null)
            {
                this.indentAdorner.InvalidateVisual();
            }
        }

        private AutoWrapType autoWrap = AutoWrapType.FromDoc;

        public AutoWrapType AutoWrap
        {
            get
            {
                return autoWrap;
            }
            set
            {
                if (autoWrap != value)
                {
                    autoWrap = value;
                    this.XmlData.SetAttribute("AutoWrap", autoWrap.ToString());
                }

                //为便于绑定的刷新，这个放到外面。
                OnPropertyChanged(this, new PropertyChangedEventArgs("AutoWrap"));
            }
        }
    }
}
